package la.bbs558.util;

import cn.hutool.core.stream.StreamUtil;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @Classname Objects
 * @Description 流操作的工具类
 * @Date 2023/8/16 11:12
 * @Created by weihanmin
 */
public class Streams extends StreamUtil {

    public static <K, V> Map<K, V> listToMap(List<V> list,Function<? super V, ? extends K> keyMapper, BinaryOperator<V> merge) {
        if (Objs.isInvalid(list)) {
            return new LinkedHashMap<>();
        }
        return list.stream().collect(Collectors.toMap(keyMapper,Function.identity(), merge));
    }

    public static <V> BinaryOperator<V> mergeBefore() {
        return (a, b)->b;
    }

    public static <V> BinaryOperator<V> mergeAfter() {
        return (a, b)->a;
    }

    public static <R, T> List<R> listToList(List<T> list, Function<T, R> mapper) {
        if (Objs.isInvalid(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(mapper).collect(Collectors.toList());
    }

    //无序的map
    public static <K, V> Map<K, List<V>> listGroupingBy(List<V> list, Function<? super V, ? extends K> groupBy) {
        if (Objs.isInvalid(list)) {
            return new LinkedHashMap<>();
        }
        return list.stream().collect(Collectors.groupingBy(groupBy));
    }

    //有序的map
    public static <K, V> Map<K, List<V>> sortListGroupingBy(List<V> list, Function<? super V, ? extends K> groupBy) {
        if (Objs.isInvalid(list)) {
            return new LinkedHashMap<>();
        }
        // return list.stream().collect(Collectors.groupingBy(groupBy,LinkedHashMap::new,Collectors.toList()));
        Function<? super Object, ? extends V> k = (Function<Object, V>) o -> null;
        Supplier<List<V>> a = ArrayList::new;
        return list.stream().collect(Collectors.groupingBy(groupBy,Collectors.mapping(k,Collectors.toCollection(a))));
    }

    public static <T> Map<Boolean, List<T>> listPartitioningBy(List<T> list,Predicate<? super T> predicate,Collector<? super T, ?, List<T>> collectors) {
        if (Objs.isInvalid(list)) {
            return new LinkedHashMap<>();
        }
        return list.stream().collect(Collectors.partitioningBy(predicate,collectors));
    }

}
